package com.amoyt.project.service.admin.impl;

import com.amoyt.project.config.redis.RedisCache;
import com.amoyt.project.config.redis.RedisIdWork;
import com.amoyt.project.constants.IdConstants;
import com.amoyt.project.constants.RedisConstants;
import com.amoyt.project.constants.ResponseConstants;
import com.amoyt.project.domain.bo.HouseholdBo;
import com.amoyt.project.domain.dto.insert.HouseholdAddDto;
import com.amoyt.project.domain.dto.query.PovertyHouseholdPageQuery;
import com.amoyt.project.domain.dto.update.HouseholdUpdateDto;
import com.amoyt.project.domain.pojo.Address;
import com.amoyt.project.domain.pojo.DemandInfo;
import com.amoyt.project.domain.pojo.HouseholdBase;
import com.amoyt.project.domain.pojo.PovertyPerson;
import com.amoyt.project.domain.res.PageResult;
import com.amoyt.project.domain.res.Result;
import com.amoyt.project.domain.vo.DemandInfoVo;
import com.amoyt.project.domain.vo.HouseholdDetailVo;
import com.amoyt.project.domain.vo.HouseholdVo;
import com.amoyt.project.domain.vo.PersonVo;
import com.amoyt.project.exception.BusinessException;
import com.amoyt.project.exception.enums.BusinessExceptionEnum;
import com.amoyt.project.mapper.AddressMapper;
import com.amoyt.project.mapper.PovertyDemandInfoMapper;
import com.amoyt.project.mapper.PovertyHouseholdBaseMapper;
import com.amoyt.project.mapper.PovertyPersonMapper;
import com.amoyt.project.service.admin.PovertyHouseholdBaseService;
import com.amoyt.project.utils.ConvertBeanUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 贫困户基本信息表（家庭级） 服务实现类
 * </p>
 *
 * @author AmoyT
 * @since 2025-08-21
 */
@Service
public class PovertyHouseholdBaseServiceImpl implements PovertyHouseholdBaseService {

    @Autowired
    private PovertyHouseholdBaseMapper householdMapper;
    @Autowired
    private PovertyPersonMapper personMapper;
    @Autowired
    private PovertyDemandInfoMapper demandInfoMapper;
    @Autowired
    private RedisIdWork redisIdWork;
    @Autowired
    private RedisCache redisCache;
    @Autowired
    private AddressMapper addressMapper;

    @Override
    public Result list(PovertyHouseholdPageQuery query) {
        //TODO 校验参数

        //构建分页参数
        Page<HouseholdBo> page = new Page<>(query.getPage(), query.getPageSize());
        IPage<HouseholdBo> queryPage = householdMapper.queryHouseholdList(page, query);

        //处理地址 转换成HouseholdVo列表
        List<HouseholdVo> householdVoList = queryPage.getRecords().stream()
                .map(householdBo -> {
                    HouseholdVo vo = ConvertBeanUtils.convert(householdBo, HouseholdVo.class);
                    //处理地址信息
                    vo.setAddressStr(householdBo.getProvince() +"/"+ householdBo.getCity() +"/"+ householdBo.getDistrict()+"/"+ householdBo.getTown() +"/"+ householdBo.getDetailAddress());
                    return vo;
                }).collect(Collectors.toList());


        //封装结果，返回
        PageResult pageResult = PageResult.builder()
                .total(queryPage.getTotal())
                .records(householdVoList)
                .build();

        return Result.success(pageResult);
    }

    @Override
    public Result queryDetail(String householdId) {

        //三大类别基本信息，人员信息，需求信息
        HouseholdBase householdBase = householdMapper.selectById(householdId);
        List<PovertyPerson> personList = queryPersonList(householdId);
        List<DemandInfo> demandInfoList = queryDemandList(householdId);

        //拷贝
        List<PersonVo> personVoList = ConvertBeanUtils.convertList(personList, PersonVo.class);
        List<DemandInfoVo> demandInfoVoList = ConvertBeanUtils.convertList(demandInfoList, DemandInfoVo.class);
        HouseholdDetailVo householdDetailVo = ConvertBeanUtils.convert(householdBase, HouseholdDetailVo.class);
        householdDetailVo.setPersonList(personVoList);
        householdDetailVo.setDemandList(demandInfoVoList);

        return Result.success(householdDetailVo);
    }

    /**
     * 根据贫困户ID查询人员信息
     * @param householdId
     * @return
     */
    private List<PovertyPerson> queryPersonList(String householdId){
        //构造条件
        QueryWrapper<PovertyPerson> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("household_id", householdId);
        return personMapper.selectList(queryWrapper);
    }

    /**
     * 根据贫困户ID查询需求信息
     * @param householdId
     * @return
     */
    private List<DemandInfo> queryDemandList(String householdId){
        QueryWrapper<DemandInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("household_id", householdId);
        return demandInfoMapper.selectList(queryWrapper);
    }

    @Override
    @Transactional
    public Result add(Integer flag, HouseholdAddDto householdAddDto) {

        //1.新增基本信息
        //1.1 校验参数
        HouseholdBase householdBase = ConvertBeanUtils.convert(householdAddDto, HouseholdBase.class);

        //处理地址信息
        // 处理地址信息（增加异常处理和校验）
        String addressStr = householdAddDto.getAddressStr();
        if (addressStr == null || addressStr.isEmpty()) {
            throw new IllegalArgumentException("地址信息不能为空");
        }

        String[] addressParts = addressStr.split("/");
        // 校验地址分割后的长度是否符合预期（至少5部分）
        if (addressParts.length < 5) {
            throw new IllegalArgumentException("地址格式不正确，应为：省/市/区/镇/详细地址");
        }

        // 构建地址对象，注意数组索引从0开始
        Address address = Address.builder()
                .province(addressParts[0].trim())  // 去除可能的空格
                .city(addressParts[1].trim())
                .district(addressParts[2].trim())
                .town(addressParts[3].trim())
                .detailAddress(addressParts[4].trim())
                .build();

        // 插入地址信息并返回主键
        addressMapper.insert(address);
        // 如果使用的是MyBatis-Plus，插入后主键会自动回写到address对象中
        Long addressId = address.getAddressId();

        // 通常还需要将地址ID设置到householdBase中
        householdBase.setAddressId(addressId);

        //1.2 ID生成
        String householdId = IdConstants.POOR_ID_PREFIX + redisIdWork.nextId(IdConstants.POOR_ID_PREFIX);
        householdBase.setHouseholdId(householdId);
        if(flag == 1){
            //代表登记
            householdBase.setRegistrationStatus("1");
        }

        //贫困户编号设置
        //线程id作为锁
        long threadId = Thread.currentThread().getId();
        //1.先获取锁，然后查看编号，+1,释放锁
        boolean tryLock = redisCache.tryLock(RedisConstants.ICR_POVERTY_CODE_LOCK, threadId, RedisConstants.ICR_POVERTY_LOCK_TTL);
        if(!tryLock){
            return Result.error(ResponseConstants.SYSTEM_BUSY);
        }

        //获取编号
        Integer householdNumber = (Integer) redisCache.getCacheObject(RedisConstants.ICR_POVERTY_CODE);
        if (householdNumber == null){
            //空说明是第一个
            householdNumber = 10100000;
            //设置下一个
            redisCache.setCacheObject(RedisConstants.ICR_POVERTY_CODE, 10100001);
        }else {
            //自增一下
            redisCache.increment(RedisConstants.ICR_POVERTY_CODE);
        }
        //释放锁,要判断是否是自己（当前线程）的锁
        redisCache.unLock(RedisConstants.ICR_POVERTY_CODE_LOCK, threadId);

        householdBase.setHouseholdNumber("G-"+householdNumber);


        //2.新增人员信息 (处理数据)
        List<PovertyPerson> personList = householdAddDto.getPersonList().stream()
                .map(personAddDto -> {
                    //转换
                    PovertyPerson povertyPerson = ConvertBeanUtils.convert(personAddDto, PovertyPerson.class);
                    //设置
                    povertyPerson.setHouseholdId(householdId);
                    String personId = IdConstants.PERSON_INFO_ID_PREFIX + redisIdWork.nextId(IdConstants.PERSON_INFO_ID_PREFIX);
                    povertyPerson.setPersonId(personId);
                    return povertyPerson;
                })
                .collect(Collectors.toList());


        //3.新增需求信息
        List<DemandInfo> demandInfoList = householdAddDto.getDemandList().stream()
                .map(demandInfoAddDto -> {
                    //转换
                    DemandInfo demandInfo = ConvertBeanUtils.convert(demandInfoAddDto, DemandInfo.class);
                    //设置
                    demandInfo.setHouseholdId(householdId);
                    String demandId = IdConstants.DEMAND_ID_PREFIX + redisIdWork.nextId(IdConstants.DEMAND_ID_PREFIX);
                    demandInfo.setDemandId(demandId);
                    return demandInfo;
                }).collect(Collectors.toList());

        //插入
        householdMapper.insert(householdBase);
        personMapper.insertBatchList(personList);
        demandInfoMapper.insertBatchList(demandInfoList);

        //删除缓存data
        redisCache.deleteObject(RedisConstants.CACHE_POVERTY_DATA);

        return flag == 1 ? Result.success(ResponseConstants.REGISTER_SUCCESS,null) : Result.success(ResponseConstants.SAVE_SUCCESS,null);
    }

    @Override
    public Result delete(List<String> householdIds) {
        //TODO
        return Result.error("暂未实现");
    }

    @Override
    public Result update(HouseholdUpdateDto householdUpdateDto) {

        //TODO
        //修改
        return Result.error("暂未实现");
    }
}
